/**
服务器功能
1. 消息 转发
2. 储存 用户的公钥




*/


extern crate mio;

use std::collections::HashMap;
use std::io::*;
use mio::net::{TcpListener, TcpStream};
use mio::{Token, Poll, Ready, PollOpt, Events};
use std::iter::Map;



fn procMessage(data: &[u8]) -> (bool, u8, usize, Vec<u8>)
{
    if data.len() > 2 {
        let _type = (data[0] - 48) as u8;

        let _uid = data[1] - 48;
        let _uid = _uid as usize;
        let databuff = &data[2..];
        println!("data {:?}", databuff);
        println!("uid = {} ", _uid);
        (true, _type, _uid, databuff.to_vec())
    } else {
        (false, 0, 0, vec![0])
    }
}

fn proc_im(clients_map: &HashMap<usize, TcpStream>, client_id: usize, poll: &Poll, buff: &[u8], len: usize, pollopts: PollOpt, key_map: &HashMap<String, String>)
{
    println!("Received  {} Bytes", len);
    let (ok, t, uid, buf) = procMessage(&buff[0..len]);
    println!("ok = {} , t = {} , uid = {} ", ok, t, uid);
    if !ok {
        println!("no support");
    }

    if t == 1 {
        //  聊天 模块
        let isok = match clients_map.get(&uid) {
            Some(send_client) => {
                poll.reregister(
                    send_client,
                    Token(uid),
                    Ready::writable(),
                    pollopts,
                ).unwrap();//读完了 就开始准备写
                true
            }
            None => {
                println!("no find");
                false
            }
        };

        let respose = if isok {
            "\x00\x00ok"
        } else {
            "\x00\x00no"
        };
        let mut stream = clients_map.get(&client_id).unwrap();//移除流TCP在stream生命周期结束后主动关闭

        match stream.write(respose.as_bytes()) {
            // 发送成功
            Ok(nwrite) => println!("respose ok"),
            Err(e) => println!("write err  {}", e),
        }
    } else if t == 2 {
        // 业务模块
        let respose = "200";
        let mut stream = clients_map.get(&client_id).unwrap();//移除流TCP在stream生命周期结束后主动关闭

        match stream.write(respose.as_bytes()) {
            // 发送成功
            Ok(nwrite) => println!("respose ok"),
            Err(e) => println!("write err  {}", e),
        }
    }
}

fn main() {
    //创建一个Token
    const SERVER: Token = Token(0);
    let mut curr_client_id = 1;


    let mut key_map: HashMap<String, String> = HashMap::new();

    // 设置服务器地址
    let tcp_addr = "127.0.0.1:9000".parse().unwrap();
    //绑定 服务端地址 到 tcp监听器
    let tcp_server = TcpListener::bind(&tcp_addr).unwrap();
    // 创建poll 对象及配置
    let poll = Poll::new().unwrap();
    let pollopts = if cfg!(feature = "level") {
        PollOpt::level()
    } else {
        if cfg!(feature = "oneshot") {
            PollOpt::edge() | PollOpt::oneshot()
        } else {
            PollOpt::edge()
        }
    };

    // 注册 tcp 服务器 到 token
    poll.register(&tcp_server, SERVER, Ready::readable(), PollOpt::edge())
        .unwrap();

    // 创建储存事件读对象
    let mut events = Events::with_capacity(1024); // 设置事件容量大小
    let buf = &mut [0u8; 1024]; // socket buff
    let mut amt = 0; // 当前 读取的 buff 长度
    // 流存储map
    let mut streams = HashMap::new();//只要流保存了，TCP连接就不关闭，根据客户端的id取流
    // 主循环
    loop {
        poll.poll(&mut events, None).unwrap();
        // 迭代事件
        for event in events.iter() {
            match event.token() {
                SERVER => {
                    // 读取流
                    let (stream, _addr) = tcp_server.accept().unwrap();
                    let client_id = curr_client_id;
                    curr_client_id += 1;
                    let token = Token(client_id);
                    //将流存进streams map
                    if let Some(_stream) = streams.insert(client_id, stream) {
                        panic!("Stream entry token filled.");
                    }
                    // 注册一个新的事件 等待下一次 循环 取出 实件类型是可读
                    poll.register(&streams[&client_id], token, Ready::readable(), pollopts)
                        .unwrap();//为每一个新的TCP 客户端注册不同的token
                }
                // 客户端 任务 有 SERVER 事件注册 产生
                Token(client_id) => {
                    // 如果新的事件产生 会进入这里
                    if event.readiness().is_readable() {
                        // 事件是可读类型 进入这里，获取 客户端的流
                        let stream = streams.get_mut(&client_id).unwrap();
                        // 读取buff
                        match stream.read(buf) {
                            Ok(nread) => {
                                amt = nread;
                                //TODO
                                // println!("data buff = {:?}" , &buf);
                                proc_im(&streams, client_id, &poll, buf, amt, pollopts, &key_map);
                                // data.write_all(buf);
                                // println!("data buff ={:?}" , &buf);
                            }
                            Err(e) => println!("read err  {}", e),
                        }
                        println!("send ok ");
                    }
                    if event.readiness().is_writable() {
                        // 同理 可写事件进入这里
                        // 读取流

                        let mut stream = streams.get(&client_id).unwrap();//移除流TCP在stream生命周期结束后主动关闭
                        buf[0]=1;
                        buf[0]=0;
                        match stream.write(&buf[2..amt]) {
                            // 发送成功

                            Ok(nwrite) => println!("write  {} Bytes , data {:?}", nwrite, &buf[0..amt]),
                            Err(e) => println!("write err  {}", e),
                        }
                        poll.reregister(
                            stream,
                            Token(client_id),
                            Ready::readable(),
                            pollopts,
                        ).unwrap();//读完了 就开始准备写
                    }
                }
                // 其他事件
                _ => unreachable!(),
            }
        }
    }
}